console.log("12QuadTree");

let utils = data["utils"];
let RBushItem = data["RBushItem"];
let RBU = data["RBU"];
let RBush = data["RBush"];
let AreaForRender = data["AreaForRender"];
let quickselect = data["quickselect"];
let SphericalMercator = data["SphericalMercator"];
let PointItem = data["PointItem"];
let PointForRender = data["PointForRender"];
let BoundsItem = data["BoundsItem"];
let LeftNumFunnel = data["LeftNumFunnel"];

var boundsContain = BoundsItem.boundsContain,
  boundsIntersect = BoundsItem.boundsIntersect;

function QuadTree(bounds, pointQuad, maxDepth, maxChildren) {
  var node;
  node = new Node(bounds, 0, maxDepth, maxChildren);
  this.root = node;
}
utils.extend(QuadTree.prototype, {
  root: null,
  insert: function (item) {
    if (item instanceof Array) {
      var i, len = item.length;
      for (i = 0; i < len; i++) this.root.insert(item[i]);
    } else this.root.insert(item);
  },
  clear: function () {
    this.root.clear();
  },
  findContainerNode: function (item) {
    return this.root.findContainerNode(item);
  },
  retrieve: function (item) {
    var out = this.root.retrieve(item).slice(0);
    return out;
  },
  nodes: null,
  children: null,
  _bounds: null,
  _depth: 0,
  _maxChildren: 4,
  _maxDepth: 4,
})

function Node(bounds, depth, maxDepth, maxChildren) {
  this._bounds = bounds;
  this._depth = depth;
  this._maxDepth = maxDepth;
  this._maxChildren = maxChildren;
  this.children = [];
  this.nodes = [];
}
utils.extend(Node.prototype, {
  getSubNodes: function () {
    return this.nodes;
  },
  getChildren: function () {
    return this.children;
  },
  isEmpty: function () {
    return 0 === this.nodes.length && 0 === this.children.length;
  },
  getTopDes: function (n, compare) {
    var subNodes, i, len, node, descendants = [],
      stack = [this];
    do {
      node = stack.pop();
      subNodes = node.getSubNodes();
      if (subNodes.length)
        for (i = 0, len = subNodes.length; i < len; i++) stack.push(subNodes[i]);
      else {
        utils.merge(descendants, node.getChildren());
        len = descendants.length;
        if (len > n) {
          quickselect(descendants, n, 0, len - 1, compare);
          descendants.length = n;
        }
      }
    } while (stack.length);
    return descendants;
  },
  getDescendants: function () {
    var subNodes, i, len, node, descendants = [],
      stack = [this];
    do {
      node = stack.pop();
      subNodes = node.getSubNodes();
      if (subNodes.length)
        for (i = 0, len = subNodes.length; i < len; i++) stack.push(subNodes[i]);
      else utils.merge(descendants, node.getChildren());
    } while (stack.length);
    return descendants;
  }
})


QuadTree.Node = Node;
QuadTree.setMaxChildrenAndDepth = function (maxChildren, maxDepth) {
  Node.prototype._maxChildren = maxChildren;
  Node.prototype._maxDepth = maxDepth;
};



return {
  "utils": utils,
  "RBushItem": RBushItem,
  "RBU": RBU,
  "RBush": RBush,
  "AreaForRender": AreaForRender,
  "LeftNumFunnel": LeftNumFunnel,
  "quickselect": quickselect,
  "SphericalMercator": SphericalMercator,
  "PointItem": PointItem,
  "PointForRender": PointForRender,
  "BoundsItem": BoundsItem,
  "QuadTree": QuadTree,
  "Node": Node,
}